'''
Created on Nov 21, 2012

@author: marco aurelio zoqui
'''
import exceptions
import logging
import urllib
import urllib2 
import webapp2
from google.appengine.ext import db
from google.appengine.api import urlfetch

from twilio import twiml


class MP3(db.Model):
    text = db.StringProperty()
    lang = db.StringProperty()
    file = db.BlobProperty()

class GoogleTTS():
    def __init__(self, key=None, text=None,lang=None):
        self.mp3 = None
        if key:
            mp3=db.get(db.Key(key))
        else:
            if text and lang: 
                mp3=db.GqlQuery("SELECT * FROM MP3 WHERE lang = :1 and text = :2",lang,text).get()
            else:
                return
        if mp3:
            self.mp3 = mp3
        else:
            mp3 = MP3(text=text,lang=lang)
            mp3.put()
            self.mp3 = mp3

                 
    def url(self, path=None):
        if path:
            return "%s%s" % (path, str(self.mp3.key()))
        else:
            return "/mp3/%s" % (str(self.mp3.key()))
                                
    def content(self):
        try:
            if not self.mp3:
                return None
            if self.mp3.file:
                return self.mp3.file
            headers = {
                "User-Agent": 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
                "Content-Type": "application/x-www-form-urlencoded"
            }               
            form_data = urllib.urlencode({
                'tl':self.mp3.lang,
                'q': self.mp3.text
            })
            url = "http://translate.google.com/translate_tts"            
            result = urlfetch.fetch(
                url=url,
                headers=headers,
                payload=form_data,
                method=urlfetch.POST
            )
            if result.status_code==200:
                self.mp3.file = result.content
                self.mp3.put()
                return self.mp3.file
        except urllib2.URLError,e:
            logging.info('urllib2.URLError: %s' % (e.message))
        except exceptions.BaseException,e:
            logging.info(e.message)
        return None

##------------------------------------------------------------------------------
# twiml Extended classes
# twiml.Say, twiml.Response twiml.Gather
#
class Say(twiml.Say):
    """Twilio SAY verb."""
    TWILIO_TTS=[twiml.Say.ENGLISH,twiml.Say.BRITISH,twiml.Say.SPANISH,twiml.Say.FRENCH,twiml.Say.GERMAN]
        
    def xml(self):
        keys = self.attrs.keys()
        if 'language' in keys and self.attrs['language'] not in self.TWILIO_TTS: 
            if __package__: 
                path='/%s/mp3/'%(__package__)
            else:
                path='/mp3/'
            url = GoogleTTS(lang=self.attrs['language'],text=self.body).url(path)
            return twiml.Play(url=url).xml()                                
        return super(twiml.Say,self).xml()

class Gather(twiml.Gather):
    """Twilio Gather verb."""
    def say(self, text, **kwargs):
        return self.append(Say(text, **kwargs))

class Response(twiml.Response):
    """Twilio response xml."""
    def say(self, text, **kwargs):
        return self.append(Say(text, **kwargs))

    def gather(self, **kwargs):
        return self.append(Gather(**kwargs))

##------------------------------------------------------------------------------
class MP3Handler(webapp2.RequestHandler):
    def initialize(self, request, response):
        super(MP3Handler,self).initialize(request, response)

    def get(self):
        try:
            key = self.request.url.split('/')[-1]
            if key:
                tts = GoogleTTS(key=key)
                if tts.mp3:
                    content = tts.content()
                    if content:
                        self.response.set_status(200)
                        self.response.headers['Content-Type'] = "audio/mp3"
                        self.response.out.write(content)
                        return
 
        except:
            pass
        self.response.set_status(404)
